package com.jumi.microservice.wdt;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jumi.microservice.dto.order.DeliverGoodsRequest;
import com.jumi.microservice.dto.wdt.PushOrderRequest;
import com.jumi.microservice.dto.wdt.WdtGoodsRequest;
import com.jumi.microservice.dto.wdt.WdtOrderRequest;
import com.jumi.microservice.dto.wdt.WdtResultResponse;
import com.jumi.microservice.entity.LogisticsGoods;
import com.jumi.microservice.entity.OrderLogistics;
import com.jumi.microservice.enumerate.LogisticsStatusEnum;
import com.jumi.microservice.enumerate.SelfFlagEnum;
import com.jumi.microservice.mapper.LogisticsGoodsMapper;
import com.jumi.microservice.mapper.OrderLogisticsMapper;
import com.jumi.microservice.service.IOrderDubboService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Dirk
 * @Date 2020-08-15 10:31
 */
@Service
@RefreshScope
public class WdtService {

    private static final Logger log = LoggerFactory.getLogger(WdtService.class);

    @Value("${wdt.repo:0}")
    private String wdtWarehouse;

    @Resource
    private WdtOrderClient wdtOrderClient;

    @Resource
    private OrderLogisticsMapper orderLogisticsMapper;

    @Resource
    private LogisticsGoodsMapper logisticsGoodsMapper;

    @DubboReference
    private IOrderDubboService orderDubboService;

    @Resource
    private WdtRequestConvert wdtRequestConvert;

    public WdtResultResponse pushOrder(PushOrderRequest pushOrderRequest) {
        WdtResultResponse wdtResultResponse = new WdtResultResponse();
        List<String> logisticsNos = pushOrderRequest.getOrderLogisticsNos();
        List<LogisticsGoods> logisticsGoodsList;
        QueryWrapper<LogisticsGoods> logisticsGoodsQueryWrapper = new QueryWrapper<>();
        logisticsGoodsQueryWrapper.eq("del_flag", 0).eq("self_flag", SelfFlagEnum.YES_SELF.getCode())
                .eq("is_wdt_push", 0).eq("logistics_status", LogisticsStatusEnum.WAIT_SEND.getCode())
                .eq("real_warehouse",Integer.parseInt(wdtWarehouse));
        if (pushOrderRequest.getBenchmarkTime() != null) {
            logisticsGoodsQueryWrapper.le("create_time", pushOrderRequest.getBenchmarkTime());
        }
        if (logisticsNos != null) {
            // 查询选中旺店通待发货包裹商品
            logisticsGoodsQueryWrapper.in("logistics_no", logisticsNos);
        }
        // 查询所有旺店通待发货包裹商品
        logisticsGoodsList = logisticsGoodsMapper.selectList(logisticsGoodsQueryWrapper);
        logisticsNos = logisticsGoodsList.stream().map(LogisticsGoods::getLogisticsNo).collect(Collectors.toList());
        if (logisticsNos.isEmpty()) {
            wdtResultResponse.setPushOrderNum(0);
            wdtResultResponse.setData(true);
            return wdtResultResponse;
        }
        Map<String,List<LogisticsGoods>> logisticsGoodsMap = new HashMap<>();
        for(LogisticsGoods logisticsGoods:logisticsGoodsList){
            if(logisticsGoodsMap.containsKey(logisticsGoods.getLogisticsNo())){
                logisticsGoodsMap.get(logisticsGoods.getLogisticsNo()).add(logisticsGoods);
            }else{
                List<LogisticsGoods> ll = new ArrayList<>();
                ll.add(logisticsGoods);
                logisticsGoodsMap.put(logisticsGoods.getLogisticsNo(),ll);
            }
        }
        // 查询商品所在包裹
        QueryWrapper<OrderLogistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("logistics_no", logisticsNos);
        List<OrderLogistics> orderLogisticsList = orderLogisticsMapper.selectList(queryWrapper);
        Map<String,OrderLogistics> orderLogisticsMap = new HashMap<>(orderLogisticsList.size());
        for(OrderLogistics orderLogistics:orderLogisticsList){
            orderLogisticsMap.put(orderLogistics.getLogisticsNo(),orderLogistics);
        }
        log.info("需要推单的包裹:[{}], 包含的商品为:[{}]", JSON.toJSONString(logisticsNos), JSON.toJSONString(logisticsGoodsList));
        List<LogisticsGoods> pushLogisticsGoods = new ArrayList<>();
        // data to object
        List<WdtOrderRequest> wdtOrderRequestList = new ArrayList<>();
        Set<String> set = new HashSet<>(logisticsNos);
        set.forEach(logisticsNo -> {
            List<LogisticsGoods> subLogisticsGoodsList = logisticsGoodsMap.get(logisticsNo);
            //判断下面的商品是否符合小于等于3.00KG
            if (subLogisticsGoodsList.stream().map(item -> item.getGoodsWeight().multiply(new BigDecimal(item.getGoodsAmount())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add).compareTo(new BigDecimal("3.00")) <=0) {
                WdtOrderRequest wdtOrderRequest = wdtRequestConvert.wdtOrderRequestConvert(orderLogisticsMap.get(logisticsNo));
                List<WdtGoodsRequest> wdtGoodsRequestList = wdtRequestConvert.wdtGoodsRequestsConvert(subLogisticsGoodsList);
                wdtOrderRequest.setOrderList(wdtGoodsRequestList);
                wdtOrderRequestList.add(wdtOrderRequest);
                pushLogisticsGoods.addAll(subLogisticsGoodsList);
            }
        });
        if (wdtOrderRequestList.isEmpty()) {
            wdtResultResponse.setPushOrderNum(0);
            wdtResultResponse.setData(true);
            return wdtResultResponse;
        }
        // push order
        int size = 100;
        for (int i = 1; i - size <= wdtOrderRequestList.size(); i += size) {
//            wdtOrderClient.pushOrder(wdtOrderRequestList.subList(i, Math.min(i, wdtOrderRequestList.size())));
            wdtOrderClient.pushOrder(wdtOrderRequestList.stream().skip((i-1)*size).limit(size).collect(Collectors.toList()));
        }
        //修改包裹商品为已推单
        UpdateWrapper<LogisticsGoods> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id", pushLogisticsGoods.stream().map(LogisticsGoods::getId).collect(Collectors.toList()));
        LogisticsGoods logisticsGoods = new LogisticsGoods();
        logisticsGoods.setIsWdtPush((byte) 1);
        logisticsGoodsMapper.update(logisticsGoods, updateWrapper);
        // 修改订单状态为
        DeliverGoodsRequest request = new DeliverGoodsRequest();
        request.setOrderIds(new ArrayList<>(pushLogisticsGoods.stream().map(LogisticsGoods::getOrderId).collect(Collectors.toSet())));
        orderDubboService.deliverGoods(request);
        wdtResultResponse.setPushOrderNum(wdtOrderRequestList.size());
        wdtResultResponse.setData(true);
        return wdtResultResponse;
    }

//    @Scheduled(fixedDelay = 5 * 60 * 1000)
//    public void logisticsSync() {
//        // 轮询旺店通物流状态
//        wdtOrderClient.logisticsSync();
//    }

}
